/* Copyright (c) 2004-2008, Andriy Nikolov
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.processmining.email;

/**
 * <p>Represents the type of an audit trail entry.
 *
 * @author Andriy Nikolov
 * @version 1.0
 */
public class ProcessEventType {
  String standardName;
  String aliasName;

  /**
   * Contains all possible pairs of audit trail entries following each other.
   */
  public static final String[][] precedences = {
      {"schedule", "start"},
      {"start", "complete"},
      {"resume", "complete"},
      {"suspend", "resume"},
      {"start", "suspend"},
      {"start", "abort"},
      {"resume", "abort"},
      {"schedule", "withdraw"},
      {"resume", "suspend"}
  };

  public ProcessEventType() {
  }

  public ProcessEventType(String name) {
    standardName = name;
    aliasName = name;
  }

  /**
   * Creates a process event type with a given standard name (according to
   * process mining group standards) and an alias name (the name, under which it
   * is known in the log).
   *
   * @param standard String
   * @param alias String
   */
  public ProcessEventType(String standard, String alias) {
    standardName = standard;
    aliasName = alias;
  }

  public void setStandardName(String name) {
    standardName = name;
  }

  public String getStandardName() {
    return standardName;
  }

  public void setAliasName(String name) {
    aliasName = name;
  }

  public String getAliasName() {
    return aliasName;
  }

  /**
   * Gets the order of precedence between two events.
   *
   * @param with ProcessEventType
   * @return -1 - current event precedes one given as a parameter.
   *   1 - current event succeeds one given as a parameter.
   *   0 - the order is impossible to determine.
   */
  public int compareTo(ProcessEventType with) {
    if(standardName.equals(with.getStandardName()))
      return 0;
    if(precedes(standardName, with.getStandardName()))
      return -1;
    if(succeeds(standardName, with.getStandardName()))
      return 1;
    return 0;
  }

  public static boolean precedes(String event1, String event2) {
    boolean value = false;
    if(event1.equals(event2))
      return false;
    for(int i=0;i<precedences.length;i++) {
      if(event1.equals(precedences[i][0])) {
        if(event2.equals(precedences[i][1])) {
          value = true;
        } else {
          value = precedes(precedences[i][1], event2);
        }
      }
    }
    return value;
  }

  public static boolean succeeds(String event1, String event2) {
    boolean value = false;
    if(event1.equals(event2))
      return false;
    for(int i=0;i<precedences.length;i++) {
      if(event1.equals(precedences[i][1])) {
        if(event2.equals(precedences[i][0])) {
          value = true;
        } else {
          value = succeeds(precedences[i][0], event2);
        }
      }
    }
    return value;
  }

  public static boolean directlyPrecedes(String event1, String event2) {
    for(int i=0;i<precedences.length;i++) {
      if (event1.equals(precedences[i][0])) {
        if (event2.equals(precedences[i][1])) {
          return true;
        }
      }
    }
    return false;
  }

  public static boolean directlySucceeds(String event1, String event2) {
    for(int i=0;i<precedences.length;i++) {
      if (event1.equals(precedences[i][1])) {
        if (event2.equals(precedences[i][0])) {
          return true;
        }
      }
    }
    return false;
  }

  public boolean directlyPrecedes(ProcessEventType event) {
    return directlyPrecedes(standardName, event.getStandardName());
  }

  public boolean directlySucceeds(ProcessEventType event) {
    return directlySucceeds(standardName, event.getStandardName());
  }

  public static boolean isFinal(String event1) {
    if(event1.equals("complete")||event1.equals("abort")||event1.equals("withdraw"))
      return true;
    return false;
  }

  public static boolean isStart(String event1) {
    if(event1.equals("schedule"))
      return true;
    return false;
  }

  public boolean isFinal() {
    if(ProcessEventType.isFinal(standardName))
      return true;
    return false;
  }

  public boolean isStart() {
    if(ProcessEventType.isStart(standardName))
      return true;
    return false;
  }

  public String getNextTypeName() {
    String value;
    if(isFinal())
      return null;
    for(int i=0;i<precedences.length;i++) {
      if(precedences[i][0].equals(standardName))
        return precedences[i][1];
    }
    return null;
  }

  public String getPreviousTypeName() {
    String value;
    if(isStart())
      return null;
    for(int i=0;i<precedences.length;i++) {
      if(precedences[i][1].equals(standardName))
        return precedences[i][0];
    }
    return null;
  }
}
